/*     */ package com.zimbra.cs.lmtpserver.utils;
/*     */ 
/*     */ import com.zimbra.common.lmtp.LmtpClient;
/*     */ import com.zimbra.common.lmtp.LmtpClient.Protocol;
/*     */ import com.zimbra.common.util.ByteUtil;
/*     */ import com.zimbra.common.util.CliUtil;
/*     */ import com.zimbra.common.util.EmailUtil;
/*     */ import com.zimbra.common.util.FileUtil;
/*     */ import com.zimbra.common.util.Log;
/*     */ import com.zimbra.common.util.LogFactory;
/*     */ import java.io.BufferedInputStream;
/*     */ import java.io.File;
/*     */ import java.io.FileInputStream;
/*     */ import java.io.IOException;
/*     */ import java.io.InputStream;
/*     */ import java.io.PrintStream;
/*     */ import java.util.ArrayList;
/*     */ import java.util.Collections;
/*     */ import java.util.Iterator;
/*     */ import java.util.List;
/*     */ import java.util.zip.GZIPInputStream;
/*     */ import org.apache.commons.cli.CommandLine;
/*     */ import org.apache.commons.cli.CommandLineParser;
/*     */ import org.apache.commons.cli.GnuParser;
/*     */ import org.apache.commons.cli.HelpFormatter;
/*     */ import org.apache.commons.cli.Option;
/*     */ import org.apache.commons.cli.OptionBuilder;
/*     */ import org.apache.commons.cli.Options;
/*     */ import org.apache.commons.cli.ParseException;
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ public class LmtpInject
/*     */ {
/*  52 */   private static Log mLog = LogFactory.getLog(LmtpInject.class);
/*     */   
/*  54 */   private static Options mOptions = new Options();
/*     */   
/*     */   private String mSender;
/*     */   private String[] mRecipients;
/*     */   private List<File> mFiles;
/*     */   private String mHost;
/*     */   private int mPort;
/*     */   private LmtpClient.Protocol mProto;
/*  62 */   private int mCurrentFileIndex = 0;
/*     */   
/*     */   private int mSucceeded;
/*     */   
/*     */   private int mFailed;
/*     */   private int mIgnored;
/*     */   private long mStartTime;
/*     */   private long mLastProgressTime;
/*     */   private int mLastProgressCount;
/*  71 */   private boolean mQuietMode = false;
/*  72 */   private boolean mVerbose = false;
/*     */   
/*  74 */   private volatile long mFileSizeTotal = 0L;
/*     */   
/*     */ 
/*     */ 
/*     */   private int mNumThreads;
/*     */   
/*     */ 
/*     */ 
/*     */   private boolean skipTLSCertValidation;
/*     */   
/*     */ 
/*     */ 
/*     */ 
/*     */   private LmtpInject(int numThreads, String sender, String[] recipients, List<File> files, String host, int port, LmtpClient.Protocol proto, boolean quietMode, boolean tracingEnabled, boolean verbose, boolean skipTLSCertValidation)
/*     */     throws Exception
/*     */   {
/*  90 */     this.mNumThreads = numThreads;
/*  91 */     this.mSender = sender;
/*  92 */     this.mRecipients = recipients;
/*  93 */     this.mFiles = files;
/*  94 */     this.mHost = host;
/*  95 */     this.mPort = port;
/*  96 */     this.mProto = proto;
/*  97 */     this.mSucceeded = (this.mFailed = this.mIgnored = 0);
/*  98 */     this.mStartTime = (this.mLastProgressTime = 0L);
/*  99 */     this.mLastProgressCount = 0;
/* 100 */     this.mQuietMode = quietMode;
/* 101 */     this.mVerbose = verbose;
/* 102 */     this.skipTLSCertValidation = skipTLSCertValidation;
/*     */   }
/*     */   
/*     */   public synchronized void markStartTime() {
/* 106 */     this.mStartTime = (this.mLastProgressTime = System.currentTimeMillis());
/*     */   }
/*     */   
/* 109 */   private int mReportEvery = 100;
/* 110 */   public synchronized void setReportEvery(int num) { this.mReportEvery = num; }
/*     */   
/*     */   public void incSuccess()
/*     */   {
/* 114 */     int lastCount = 0;
/* 115 */     long lastTime = 0L;
/* 116 */     long startTime = 0L;
/* 117 */     long now = 0L;
/* 118 */     boolean report = false;
/*     */     int count;
/* 120 */     synchronized (this) {
/* 121 */       count = ++this.mSucceeded;
/* 122 */       if (count % this.mReportEvery == 0) {
/* 123 */         report = true;
/* 124 */         startTime = this.mStartTime;
/* 125 */         lastCount = this.mLastProgressCount;
/* 126 */         lastTime = this.mLastProgressTime;
/* 127 */         this.mLastProgressCount = count;
/* 128 */         now = System.currentTimeMillis();
/* 129 */         this.mLastProgressTime = now;
/*     */       }
/*     */     }
/* 132 */     if ((report) && (!this.mQuietMode)) {
/* 133 */       long elapsed = now - lastTime;
/* 134 */       long howmany = count - lastCount;
/* 135 */       double rate = 0.0D;
/* 136 */       if (elapsed > 0L) {
/* 137 */         rate = howmany * 1000.0D / elapsed;
/*     */       }
/* 139 */       long elapsedTotal = now - startTime;
/* 140 */       double rateAvg = 0.0D;
/* 141 */       if (elapsedTotal > 0L) {
/* 142 */         rateAvg = count * 1000.0D / elapsedTotal;
/*     */       }
/* 144 */       System.out.printf("[progress] %d msgs in %dms @ %.2fmps; last %d msgs in %dms @ %.2fmps\n", new Object[] { Integer.valueOf(count), Long.valueOf(elapsedTotal), Double.valueOf(rateAvg), Long.valueOf(howmany), Long.valueOf(elapsed), Double.valueOf(rate) });
/*     */     }
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/* 152 */   public synchronized void incFailure() { this.mFailed += 1; }
/* 153 */   public synchronized void incIgnored() { this.mIgnored += 1; }
/* 154 */   public synchronized int getSuccessCount() { return this.mSucceeded; }
/* 155 */   public synchronized int getFailureCount() { return this.mFailed; }
/* 156 */   public String getSender() { return this.mSender; }
/*     */   
/* 158 */   String getHost() { return this.mHost; }
/* 159 */   int getPort() { return this.mPort; }
/* 160 */   LmtpClient.Protocol getProtocol() { return this.mProto; }
/* 161 */   boolean isVerbose() { return this.mVerbose; }
/*     */   
/* 163 */   public boolean isSkipTLSCertValidation() { return this.skipTLSCertValidation; }
/*     */   
/* 165 */   boolean isQuiet() { return this.mQuietMode; }
/*     */   
/*     */ 
/*     */ 
/*     */ 
/*     */   synchronized File getNextFile()
/*     */   {
/* 172 */     if (this.mCurrentFileIndex >= this.mFiles.size()) {
/* 173 */       return null;
/*     */     }
/* 175 */     return (File)this.mFiles.get(this.mCurrentFileIndex++);
/*     */   }
/*     */   
/*     */   public String[] getRecipients() {
/* 179 */     return this.mRecipients;
/*     */   }
/*     */   
/*     */   public void addToFileSizeTotal(long size) {
/* 183 */     this.mFileSizeTotal += size;
/*     */   }
/*     */   
/*     */   private void run() throws IOException
/*     */   {
/* 188 */     Thread[] threads = new Thread[this.mNumThreads];
/*     */     
/*     */ 
/* 191 */     for (int i = 0; i < this.mNumThreads; i++) {
/* 192 */       threads[i] = new Thread(new LmtpInjectTask(this));
/* 193 */       threads[i].start();
/*     */     }
/*     */     
/*     */ 
/* 197 */     for (int i = 0; i < this.mNumThreads; i++) {
/*     */       try {
/* 199 */         threads[i].join();
/*     */       }
/*     */       catch (InterruptedException e) {}
/*     */     }
/*     */   }
/*     */   
/*     */   private static class LmtpInjectTask implements Runnable
/*     */   {
/*     */     private LmtpInject mDriver;
/*     */     private LmtpClient mClient;
/*     */     
/*     */     public LmtpInjectTask(LmtpInject driver) throws IOException {
/* 211 */       this.mDriver = driver;
/* 212 */       this.mClient = new LmtpClient(driver.getHost(), driver.getPort(), this.mDriver.getProtocol(), this.mDriver.isSkipTLSCertValidation());
/* 213 */       if ((this.mDriver.isVerbose()) && (!this.mDriver.isQuiet())) {
/* 214 */         this.mClient.quiet(false);
/*     */       } else {
/* 216 */         this.mClient.quiet(true);
/*     */       }
/*     */     }
/*     */     
/*     */     public void run() {
/* 221 */       File file = this.mDriver.getNextFile();
/* 222 */       while (file != null) {
/* 223 */         InputStream in = null;
/*     */         try {
/* 225 */           boolean ok = false;
/*     */           
/*     */           long dataLength;
/* 228 */           if (FileUtil.isGzipped(file)) {
/* 229 */             long dataLength = ByteUtil.getDataLength(new GZIPInputStream(new FileInputStream(file)));
/* 230 */             in = new GZIPInputStream(new FileInputStream(file));
/*     */           } else {
/* 232 */             dataLength = file.length();
/* 233 */             in = new FileInputStream(file);
/*     */           }
/*     */           
/* 236 */           ok = this.mClient.sendMessage(in, this.mDriver.getRecipients(), this.mDriver.getSender(), file.getName(), Long.valueOf(dataLength));
/* 237 */           if (ok) {
/* 238 */             this.mDriver.incSuccess();
/* 239 */             this.mDriver.addToFileSizeTotal(file.length());
/*     */           } else {
/* 241 */             this.mDriver.incFailure();
/*     */           }
/*     */         } catch (Exception e) {
/* 244 */           this.mDriver.incFailure();
/* 245 */           LmtpInject.mLog.warn("Delivery failed for " + file.getPath() + ": ", e);
/*     */         } finally {
/* 247 */           ByteUtil.closeStream(in);
/*     */         }
/* 249 */         file = this.mDriver.getNextFile();
/*     */       }
/* 251 */       this.mClient.close();
/*     */     }
/*     */   }
/*     */   
/*     */   static {
/* 256 */     mOptions.addOption("d", "directory", true, "message file directory");
/* 257 */     mOptions.addOption("a", "address", true, "lmtp server (default localhost)");
/* 258 */     mOptions.addOption("p", "port", true, "lmtp server port (default 7025)");
/* 259 */     OptionBuilder.withLongOpt("sender");OptionBuilder.hasArg(true);OptionBuilder.withDescription("envelope sender (mail from)");mOptions.addOption(OptionBuilder.create("s"));
/*     */     
/* 261 */     Option ropt = new Option("r", "recipient", true, "envelope recipients (rcpt to).  This option accepts multiple arguments, so it can't be last if a list of input files is used.");
/*     */     
/*     */ 
/* 264 */     ropt.setArgs(-2);
/* 265 */     OptionBuilder.withLongOpt("recipient");OptionBuilder.hasArgs(-2);OptionBuilder.withDescription("envelope recipients (rcpt to).  This option accepts multiple arguments, so it can't be last if a list of input files is used.");mOptions.addOption(OptionBuilder.create("r"));
/*     */     
/*     */ 
/*     */ 
/* 269 */     mOptions.addOption("t", "threads", true, "number of worker threads (default 1)");
/* 270 */     mOptions.addOption("q", "quiet", false, "don't print status");
/* 271 */     mOptions.addOption("T", "trace", false, "trace server/client traffic");
/* 272 */     mOptions.addOption("N", "every", true, "report progress after every N messages (default 100)");
/* 273 */     mOptions.addOption(null, "smtp", false, "use SMTP protocol instead of LMTP");
/* 274 */     mOptions.addOption("h", "help", false, "display usage information");
/* 275 */     mOptions.addOption("v", "verbose", false, "print detailed delivery status");
/* 276 */     mOptions.addOption(null, "noValidation", false, "don't validate file content");
/* 277 */     mOptions.addOption(null, "skipTLSCertValidation", false, "don't validate server certifcate during TLS handshake");
/*     */   }
/*     */   
/*     */   private static void usage(String errmsg) {
/* 281 */     if (errmsg != null) {
/* 282 */       mLog.error(errmsg);
/*     */     }
/* 284 */     HelpFormatter formatter = new HelpFormatter();
/* 285 */     formatter.printHelp("zmlmtpinject -r <recip1> [recip2 ...] -s <sender> [options]", "  <file1 [file2 ...] | -d <dir>>", mOptions, "Specified paths contain rfc822 messages.  Files may be gzipped.");
/*     */     
/*     */ 
/*     */ 
/*     */ 
/* 290 */     System.exit(errmsg == null ? 0 : 1);
/*     */   }
/*     */   
/*     */   private static CommandLine parseArgs(String[] args) {
/* 294 */     StringBuffer gotCL = new StringBuffer("cmdline: ");
/* 295 */     for (int i = 0; i < args.length; i++) {
/* 296 */       gotCL.append("'").append(args[i]).append("' ");
/*     */     }
/*     */     
/*     */ 
/* 300 */     CommandLineParser parser = new GnuParser();
/* 301 */     CommandLine cl = null;
/*     */     try {
/* 303 */       cl = parser.parse(mOptions, args);
/*     */     } catch (ParseException pe) {
/* 305 */       usage(pe.getMessage());
/*     */     }
/* 307 */     return cl;
/*     */   }
/*     */   
/*     */   public static void main(String[] args) {
/* 311 */     CliUtil.toolSetup();
/* 312 */     CommandLine cl = parseArgs(args);
/*     */     
/* 314 */     if (cl.hasOption("h")) {
/* 315 */       usage(null);
/*     */     }
/* 317 */     boolean quietMode = cl.hasOption("q");
/* 318 */     int threads = 1;
/* 319 */     if (cl.hasOption("t")) {
/* 320 */       threads = Integer.valueOf(cl.getOptionValue("t")).intValue();
/*     */     }
/*     */     
/* 323 */     String host = null;
/* 324 */     if (cl.hasOption("a")) {
/* 325 */       host = cl.getOptionValue("a");
/*     */     } else {
/* 327 */       host = "localhost";
/*     */     }
/*     */     
/*     */ 
/* 331 */     LmtpClient.Protocol proto = null;
/* 332 */     int port; int port; if (cl.hasOption("smtp")) {
/* 333 */       proto = LmtpClient.Protocol.SMTP;
/* 334 */       port = 25;
/*     */     } else {
/* 336 */       port = 7025; }
/* 337 */     if (cl.hasOption("p")) {
/* 338 */       port = Integer.valueOf(cl.getOptionValue("p")).intValue();
/*     */     }
/* 340 */     String[] recipients = cl.getOptionValues("r");
/* 341 */     String sender = cl.getOptionValue("s");
/* 342 */     boolean tracingEnabled = cl.hasOption("T");
/*     */     int everyN;
/*     */     int everyN;
/* 345 */     if (cl.hasOption("N")) {
/* 346 */       everyN = Integer.valueOf(cl.getOptionValue("N")).intValue();
/*     */     } else {
/* 348 */       everyN = 100;
/*     */     }
/*     */     
/*     */ 
/* 352 */     List<File> files = new ArrayList();
/* 353 */     if (cl.hasOption("d")) {
/* 354 */       File dir = new File(cl.getOptionValue("d"));
/* 355 */       if (!dir.isDirectory()) {
/* 356 */         System.err.format("%s is not a directory.\n", new Object[] { dir.getPath() });
/* 357 */         System.exit(1);
/*     */       }
/* 359 */       File[] fileArray = dir.listFiles();
/* 360 */       if ((fileArray == null) || (fileArray.length == 0)) {
/* 361 */         System.err.format("No files found in directory %s.\n", new Object[] { dir.getPath() });
/*     */       }
/* 363 */       Collections.addAll(files, fileArray);
/*     */     }
/*     */     
/*     */ 
/* 367 */     for (String arg : cl.getArgs()) {
/* 368 */       files.add(new File(arg));
/*     */     }
/*     */     
/*     */ 
/* 372 */     if (!cl.hasOption("noValidation")) {
/* 373 */       Iterator<File> i = files.iterator();
/* 374 */       while (i.hasNext()) {
/* 375 */         InputStream in = null;
/* 376 */         File file = (File)i.next();
/* 377 */         boolean valid = false;
/*     */         try {
/* 379 */           in = new FileInputStream(file);
/* 380 */           if (FileUtil.isGzipped(file)) {
/* 381 */             in = new GZIPInputStream(in);
/*     */           }
/* 383 */           in = new BufferedInputStream(in);
/* 384 */           if (!EmailUtil.isRfc822Message(in)) {
/* 385 */             System.err.format("%s does not contain a valid RFC 822 message.\n", new Object[] { file.getPath() });
/*     */           } else {
/* 387 */             valid = true;
/*     */           }
/*     */         } catch (IOException e) {
/* 390 */           System.err.format("Unable to validate %s: %s.\n", new Object[] { file.getPath(), e.toString() });
/*     */         } finally {
/* 392 */           ByteUtil.closeStream(in);
/*     */         }
/* 394 */         if (!valid) {
/* 395 */           i.remove();
/*     */         }
/*     */       }
/*     */     }
/*     */     
/* 400 */     if (files.size() == 0) {
/* 401 */       System.err.println("No files to inject.");
/* 402 */       System.exit(1);
/*     */     }
/*     */     
/* 405 */     if (!quietMode) {
/* 406 */       System.out.format("Injecting %d message(s) to %d recipient(s).  Server %s, port %d, using %d thread(s).\n", new Object[] { Integer.valueOf(files.size()), Integer.valueOf(recipients.length), host, Integer.valueOf(port), Integer.valueOf(threads) });
/*     */     }
/*     */     
/*     */ 
/* 410 */     int totalFailed = 0;
/* 411 */     int totalSucceeded = 0;
/* 412 */     long startTime = System.currentTimeMillis();
/* 413 */     boolean verbose = cl.hasOption("v");
/* 414 */     boolean skipTLSCertValidation = cl.hasOption("skipTLSCertValidation");
/*     */     
/* 416 */     LmtpInject injector = null;
/*     */     try {
/* 418 */       injector = new LmtpInject(threads, sender, recipients, files, host, port, proto, quietMode, tracingEnabled, verbose, skipTLSCertValidation);
/*     */ 
/*     */     }
/*     */     catch (Exception e)
/*     */     {
/* 423 */       mLog.error("Unable to initialize LmtpInject", e);
/* 424 */       System.exit(1);
/*     */     }
/*     */     
/* 427 */     injector.setReportEvery(everyN);
/* 428 */     injector.markStartTime();
/*     */     try {
/* 430 */       injector.run();
/*     */     } catch (IOException e) {
/* 432 */       e.printStackTrace();
/* 433 */       System.exit(1);
/*     */     }
/*     */     
/* 436 */     int succeeded = injector.getSuccessCount();
/* 437 */     int failedThisTime = injector.getFailureCount();
/* 438 */     long elapsedMS = System.currentTimeMillis() - startTime;
/* 439 */     double elapsed = elapsedMS / 1000.0D;
/* 440 */     double msPerMsg = 0.0D;
/* 441 */     double msgSizeKB = 0.0D;
/* 442 */     if (succeeded > 0) {
/* 443 */       msPerMsg = elapsedMS;
/* 444 */       msPerMsg /= succeeded;
/* 445 */       msgSizeKB = injector.mFileSizeTotal / 1024.0D;
/* 446 */       msgSizeKB /= succeeded;
/*     */     }
/* 448 */     double msgPerSec = succeeded / elapsedMS * 1000.0D;
/* 449 */     if (!quietMode) {
/* 450 */       System.out.println();
/* 451 */       System.out.printf("LmtpInject Finished\nsubmitted=%d failed=%d\n%.2fs, %.2fms/msg, %.2fmsg/s\naverage message size = %.2fKB\n", new Object[] { Integer.valueOf(succeeded), Integer.valueOf(failedThisTime), Double.valueOf(elapsed), Double.valueOf(msPerMsg), Double.valueOf(msgPerSec), Double.valueOf(msgSizeKB) });
/*     */     }
/*     */     
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/* 461 */     totalFailed += failedThisTime;
/* 462 */     totalSucceeded += succeeded;
/*     */     
/* 464 */     if (totalFailed != 0) {
/* 465 */       System.exit(1);
/*     */     }
/*     */   }
/*     */ }


/* Location:              /home/mint/zimbrastore.jar!/com/zimbra/cs/lmtpserver/utils/LmtpInject.class
 * Java compiler version: 7 (51.0)
 * JD-Core Version:       0.7.1
 */